package com.ruoyi.basebill.service.impl.billIssue.helper;

import com.ruoyi.basebill.domain.*;
import com.ruoyi.basebill.mapper.TWfzRemunerationMapper;
import com.ruoyi.basebill.service.IWfzGzffService;
import com.ruoyi.basebill.service.IWfzGzftService;
import com.ruoyi.basebill.service.IWfzGzjtService;
import com.ruoyi.basebill.service.exception.DataNullException;
import com.ruoyi.basebill.service.impl.WfzJtgzflServiceImpl;
import com.ruoyi.basebill.service.impl.billIssue.util.BillIssueUtil;
import com.ruoyi.basedata.domain.WfzBank;
import com.ruoyi.basedata.domain.WfzBankentry;
import com.ruoyi.basedata.domain.WfzBaseunit;
import com.ruoyi.basedata.domain.WfzPerson;
import com.ruoyi.basedata.mapper.WfzBankMapper;
import com.ruoyi.basedata.service.IWfzBankService;
import com.ruoyi.basedata.service.IWfzBaseunitService;
import com.ruoyi.basedata.service.impl.WfzPersonServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pushEnum.BillEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @projectName: wfz
 * @package: com.ruoyi.basebill.service.impl.billIssue.helper
 * @className: GzftHelper
 * @author: Eric
 * @description: TODO
 * @date: 2023/3/5 18:49
 * @version: 1.0
 */
@Component
public class GzftHelper {
    @Autowired
    private TWfzRemunerationMapper tWfzRemunerationMapper;
    //单据下发工具类
    @Autowired
    private BillIssueUtil billIssueUtil;
    //工资发放服务层接口
    @Autowired
    private IWfzGzffService wfzGzffService;
    //工资分摊服务层接口
    @Autowired
    private IWfzGzftService wfzGzftService;
    //工资计提服务层接口
    @Autowired
    private IWfzGzjtService wfzGzjtService;

    //组织成本中心服务层接口
    @Autowired
    private IWfzBaseunitService wfzBaseunitService;

    //人员服务层接口
    @Autowired
    private WfzPersonServiceImpl wfzPersonService;

    //薪酬总表计提工资福利服务层接口
    @Autowired
    private WfzJtgzflServiceImpl wfzJtgzflService;

    @Autowired
    private IWfzBankService wfzBankService;

    @Autowired
    private WfzBankMapper wfzBankMapper;

    public void splitBill(TWfzRemuneration tWfzRemuneration, List<TWfzRemunerationentry> tWfzRemunerationentryList, ArrayList<WfzGzft> gzfts) throws DataNullException {

        for (TWfzRemunerationentry tWfzRemunerationentry : tWfzRemunerationentryList) {

            String fpersonnumber = tWfzRemunerationentry.getFpersonnumber();

            //获取员工档案中的一级法人，将一级法人作为参数将分录划分开
            WfzPerson person = getPerson(fpersonnumber);

            if (person == null) {
                throw new DataNullException("未找到" + fpersonnumber + "员工数据");
            }
            String fsscompany = person.getFsscompany();
            String fsscost = person.getFsscost();
            String fcostcompany = person.getFcostcompany();
            String fgzffjrjg = person.getFgzffjrjg();

            WfzBaseunit unit = getUnitByGy(fsscompany);
            WfzBaseunit unitByGy = getUnitByGy(fsscost);
            WfzBaseunit compamyunitByGy1 = getUnitByGy(fcostcompany);

            if (unit == null) {
                throw new DataNullException("未找到" + fsscompany + "一级法人");
            }



            fsscompany = unit.getFnumber(); //eas编码
            String foutype = unit.getFpzz();
            fsscost = unitByGy.getFnumber(); //eas成本中心
            String fcostname = unitByGy.getFname(); //成本中心民称
            fcostcompany = compamyunitByGy1.getFnumber(); //成本中心所属财务组织
            String fcosttype = unitByGy.getFcosttype(); //成本中心属性
            String fpzz = unitByGy.getFpzz(); //凭证字

            String fbanknumber = getBankNumBycomany(fsscompany, BillEnum.GZ.toString(), fgzffjrjg);
            if(fbanknumber==null){
                throw new DataNullException("没有"+fgzffjrjg+"的银行数据");
            }
            WfzGzft gzftByCompany = judIsBill(fsscompany, gzfts);//判断是否含有同一张单据,拿到相同组织的工资发放
            if (gzftByCompany!=null) {
                //查看是否融合 ,以成本中心和银行为维度进行融合
                List<WfzGzftentry> wfzGzftentryList = gzftByCompany.getWfzGzftentryList();
                Boolean flag = false;
                for (WfzGzftentry wfzGzftentry : wfzGzftentryList) {
                    String fyhzh = wfzGzftentry.getFyhzh();
                    String fcostnumber = wfzGzftentry.getFcostnumber();
                    if (fbanknumber.equals(fyhzh) && fsscost.equals(fcostnumber)) {
                        //融合
                        String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
                        mergeGzff(wfzGzftentry,tWfzRemunerationentry);
                        flag = true;
                        if ("同组织下合并纳税成本中心".equals(jsfs)){
                            gzftByCompany.setFnscbzxrs(gzftByCompany.getFnscbzxrs().add(BigDecimal.ONE));
                        }
                        if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                            gzftByCompany.setFglf(gzftByCompany.getFglf().add(BigDecimal.ONE));
                        }
                        gzftByCompany.setFzrs(gzftByCompany.getFzrs().add(BigDecimal.ONE)); //总人数
                        break;
                    }

                }
                if (Boolean.TRUE.equals(flag)) {
                    continue;
                }
                // 未融合的单据则新增一条分录
                //新增一张单据//判断结算方式
                String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
                //如果不存在新建一个工资发放队
                //拼接分录
                WfzGzftentry wfzGzftentry = new WfzGzftentry(); //
                addGzffEntry(tWfzRemunerationentry,wfzGzftentry,fsscompany,fsscost,fcostname,fcostcompany,fcosttype,fpzz,fgzffjrjg,fbanknumber);
                if ("同组织下合并纳税成本中心".equals(jsfs)){
                    gzftByCompany.setFnscbzxrs(gzftByCompany.getFnscbzxrs().add(BigDecimal.ONE));
                }
                if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                    gzftByCompany.setFglf(gzftByCompany.getFglf().add(BigDecimal.ONE));
                }
                gzftByCompany.getWfzGzftentryList().add(wfzGzftentry);
                int size = gzftByCompany.getWfzGzftentryList().size();
                gzftByCompany.setFzrs(BigDecimal.valueOf(size)); //总人数
            } else {
                //新增一张单据
                //判断结算方式
                String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
                //如果不存在新建一个工资发放队
                WfzGzft wfzGzft = new WfzGzft();
                billIssueUtil.setBillNumber(wfzGzft);
                wfzGzft.setFperiod(tWfzRemuneration.getFperiod());
                wfzGzft.setFzrs(BigDecimal.ONE);
                if ("同组织下合并纳税成本中心".equals(jsfs)){
                    wfzGzft.setFnscbzxrs(BigDecimal.ONE);
                }
                if ("同组织下是二级组织".equals(jsfs) || "非同组织".equals(jsfs)){
                    wfzGzft.setFglf(BigDecimal.ONE);
                }
                wfzGzft.setFcompany(fsscompany);
                wfzGzft.setFvourtype(foutype);
                wfzGzft.setFcreator("admin");
                wfzGzft.setFcreatetime(new Date());
                wfzGzft.setFsourcebillid(tWfzRemuneration.getFid().toString());
                wfzGzft.setFstate("AUDIT");
                WfzGzftentry wfzGzftentry = new WfzGzftentry(); //
                //拼接分录
                addGzffEntry(tWfzRemunerationentry,wfzGzftentry,fsscompany,fsscost,fcostname,fcostcompany,fcosttype,fpzz,fgzffjrjg,fbanknumber);

                ArrayList<WfzGzftentry> wfzGzftentries = new ArrayList<>();
                wfzGzftentries.add(wfzGzftentry);
                //根据
                wfzGzft.setWfzGzftentryList(wfzGzftentries);
                gzfts.add(wfzGzft);
            }
        }
    }

    public WfzGzft judIsBill(String fssCompany,ArrayList<WfzGzft> gzfts){
        WfzGzft wfzGzft = null;
        for (WfzGzft gzft : gzfts) {
            String fcompany = gzft.getFcompany();
            if(fssCompany.equals(fcompany)){
                wfzGzft =gzft;
                break;
            }
        }
        return  wfzGzft;
    }

    /**
     * @// TODO: 2023/3/4 相同条件融合
     * @param wfzGzftentry 工资分摊分录
     * @param tWfzRemunerationentry 薪酬总表分录
     */
    public void mergeGzff(WfzGzftentry wfzGzftentry,TWfzRemunerationentry tWfzRemunerationentry ){
        BigDecimal fyfgz = tWfzRemunerationentry.getFyfgz();
        BigDecimal fgryl = tWfzRemunerationentry.getFgryl();
        BigDecimal fgryy = tWfzRemunerationentry.getFgryy();
        BigDecimal fgrgjj = tWfzRemunerationentry.getFgrgjj();
        BigDecimal fgrsy = tWfzRemunerationentry.getFgrsy();
        BigDecimal fbkgryl = tWfzRemunerationentry.getFbkgryl();
        BigDecimal fbkgryy = tWfzRemunerationentry.getFbkgryy();
        BigDecimal fbkgrsy = tWfzRemunerationentry.getFbkgrsy();
        BigDecimal fbkgrzf = tWfzRemunerationentry.getFbkgrzf();
        BigDecimal fgrgfjf = tWfzRemunerationentry.getFgrgfjf();
        BigDecimal fjrfl = tWfzRemunerationentry.getFjrfl();
        BigDecimal fgwbnf = tWfzRemunerationentry.getFgwbnf();
        BigDecimal ffhbfl = tWfzRemunerationentry.getFfhbfl();
        BigDecimal fsssdf = tWfzRemunerationentry.getFsssdf();
        BigDecimal fzkk = tWfzRemunerationentry.getFzkk();
        BigDecimal fgrsds = tWfzRemunerationentry.getFgrsds();
        BigDecimal ffk = tWfzRemunerationentry.getFfk();

        BigDecimal sfhj = fyfgz.subtract(fgryl.add(fgryy).add(fgrsy).add(fgrgjj).add(fbkgryl).add(fbkgryy).add(fbkgrsy).add(fbkgrzf).add(fgrgfjf).add(fsssdf).add(fgrsds).add(ffk).add(fzkk));



        wfzGzftentry.setFyfgz(wfzGzftentry.getFyfgz().add(tWfzRemunerationentry.getFyfgz())); //应发工资
        wfzGzftentry.setFgryl(wfzGzftentry.getFgryl().add(tWfzRemunerationentry.getFgryl())); //个人养老
        wfzGzftentry.setFgryy(wfzGzftentry.getFgryy().add(tWfzRemunerationentry.getFgryy())); //个人医疗
        wfzGzftentry.setFgrsy(wfzGzftentry.getFgrsy().add(tWfzRemunerationentry.getFgrsy())); //个人失业
//        wfzGzftentry.setFgjj(wfzGzftentry.getFgjj().add(tWfzRemunerationentry.getFgjj())); //公积金
        wfzGzftentry.setFgrgjj(wfzGzftentry.getFgrgjj().add(tWfzRemunerationentry.getFgrgjj())); //个人公积金
        wfzGzftentry.setFbkgryl(wfzGzftentry.getFbkgryl().add(tWfzRemunerationentry.getFbkgryl())); //补扣个人养老
        wfzGzftentry.setFbkgryy(wfzGzftentry.getFbkgryy().add(tWfzRemunerationentry.getFbkgryy())); //补扣个人医疗
        wfzGzftentry.setFbkgrsy(wfzGzftentry.getFbkgrsy().add(tWfzRemunerationentry.getFbkgrsy())); //补扣个人失业
        wfzGzftentry.setFbkgrzf(wfzGzftentry.getFbkgrzf().add(tWfzRemunerationentry.getFbkgrzf()));   //补扣个人住房待定
        wfzGzftentry.setFgrgfjf(wfzGzftentry.getFgrgfjf().add(tWfzRemunerationentry.getFgrgfjf()));
        wfzGzftentry.setFjrfl(wfzGzftentry.getFjrfl().add(tWfzRemunerationentry.getFjrfl())); //节日福利
        wfzGzftentry.setFgwbnf(wfzGzftentry.getFgwbnf().add(tWfzRemunerationentry.getFgwbnf())); //高温/保暖费
        wfzGzftentry.setFfhbfl(wfzGzftentry.getFfhbfl().add(tWfzRemunerationentry.getFfhbfl())); //货币型福利
        wfzGzftentry.setFsssdf(wfzGzftentry.getFsssdf().add(tWfzRemunerationentry.getFsssdf())); //代扣宿舍水电费
        wfzGzftentry.setFzkk(wfzGzftentry.getFzkk().add(tWfzRemunerationentry.getFzkk())); //质扣款
        wfzGzftentry.setFgrsds(wfzGzftentry.getFgrsds().add(tWfzRemunerationentry.getFgrsds())); //个人所得税
        wfzGzftentry.setFfk(wfzGzftentry.getFfk().add(tWfzRemunerationentry.getFfk())); //罚款
        wfzGzftentry.setFsfhj(wfzGzftentry.getFsfhj().add(sfhj)); //实发合计
    }
    /**
     * @// TODO: 2023/3/4 新增一条工资发放分录
     * @param tWfzRemunerationentry 薪酬总表分录
     * @param fsscompany 一级法人
     * @param fsscost 成本中心
     * @param fcostname 成本中心名称
     * @param fcostcompany 成本中心所属财务组织
     * @param fcosttype 成本中心属性
     * @param fpzz 凭证字
     * @param fgzffjrjg 工资计提
     * @param fbanknumber 银行账号
     */
    public void addGzffEntry(TWfzRemunerationentry tWfzRemunerationentry,WfzGzftentry wfzGzftentry,String fsscompany,String fsscost,String fcostname,String fcostcompany,String fcosttype,String fpzz,String fgzffjrjg, String fbanknumber){
        String jsfs = billIssueUtil.Jsfs(fsscompany, fsscost);//组织间结算方式
        //如果不存在新建一个工资发放队
        BigDecimal fyfgz = tWfzRemunerationentry.getFyfgz();
        BigDecimal fgryl = tWfzRemunerationentry.getFgryl();
        BigDecimal fgryy = tWfzRemunerationentry.getFgryy();
        BigDecimal fgrgjj = tWfzRemunerationentry.getFgrgjj();
        BigDecimal fgrsy = tWfzRemunerationentry.getFgrsy();
        BigDecimal fbkgryl = tWfzRemunerationentry.getFbkgryl();
        BigDecimal fbkgryy = tWfzRemunerationentry.getFbkgryy();
        BigDecimal fbkgrsy = tWfzRemunerationentry.getFbkgrsy();
        BigDecimal fbkgrzf = tWfzRemunerationentry.getFbkgrzf();
        BigDecimal fgrgfjf = tWfzRemunerationentry.getFgrgfjf();
        BigDecimal fjrfl = tWfzRemunerationentry.getFjrfl();
        BigDecimal fgwbnf = tWfzRemunerationentry.getFgwbnf();
        BigDecimal ffhbfl = tWfzRemunerationentry.getFfhbfl();
        BigDecimal fsssdf = tWfzRemunerationentry.getFsssdf();
        BigDecimal fzkk = tWfzRemunerationentry.getFzkk();
        BigDecimal fgrsds = tWfzRemunerationentry.getFgrsds();
        BigDecimal ffk = tWfzRemunerationentry.getFfk();

        BigDecimal sfhj = fyfgz.subtract(fgryl.add(fgryy).add(fgrsy).add(fgrgjj).add(fbkgryl).add(fbkgryy).add(fbkgrsy).add(fbkgrzf).add(fgrgfjf).add(fsssdf).add(fgrsds).add(ffk).add(fzkk));


        //拼接分录
        wfzGzftentry.setFyfgz(tWfzRemunerationentry.getFyfgz()); //应发工资
        wfzGzftentry.setFgryl(tWfzRemunerationentry.getFgryl()); //个人养老
        wfzGzftentry.setFgryy(tWfzRemunerationentry.getFgryy()); //个人医疗
        wfzGzftentry.setFgrsy(tWfzRemunerationentry.getFgrsy()); //个人失业
//        wfzGzftentry.setFgjj(tWfzRemunerationentry.getFgrsy()); //公积金
        wfzGzftentry.setFgrgjj(tWfzRemunerationentry.getFgrgjj()); //个人公积金
        wfzGzftentry.setFbkgryl(tWfzRemunerationentry.getFbkgryl()); //补扣个人养老
        wfzGzftentry.setFbkgryy(tWfzRemunerationentry.getFbkgryy()); //补扣个人医疗
        wfzGzftentry.setFbkgrsy(tWfzRemunerationentry.getFbkgrsy()); //补扣个人失业
        wfzGzftentry.setFbkgrzf((tWfzRemunerationentry.getFbkgrzf()));   //补扣个人住房待定
        wfzGzftentry.setFgrgfjf(tWfzRemunerationentry.getFgrgfjf());   //补扣个人公费经费待定
        wfzGzftentry.setFjrfl(tWfzRemunerationentry.getFjrfl()); //节日福利
        wfzGzftentry.setFgwbnf(tWfzRemunerationentry.getFgwbnf()); //高温/保暖费
        wfzGzftentry.setFfhbfl(tWfzRemunerationentry.getFfhbfl()); //货币型福利
        wfzGzftentry.setFsssdf(tWfzRemunerationentry.getFsssdf()); //代扣宿舍水电费
        wfzGzftentry.setFzkk(tWfzRemunerationentry.getFzkk()); //质扣款
        wfzGzftentry.setFgrsds(tWfzRemunerationentry.getFgrsds()); //个人所得税
        wfzGzftentry.setFfk(tWfzRemunerationentry.getFfk()); //罚款
        wfzGzftentry.setFsfhj(sfhj); //实发合计

        wfzGzftentry.setFcostname(fcostname);
        wfzGzftentry.setFcostnumber(fsscost);
        wfzGzftentry.setFcostcompany(fcostcompany); //c成本中心所属财务组织
        wfzGzftentry.setFjsfs(jsfs);  //结算方式

        wfzGzftentry.setFcbzxxz(fcosttype); //成本中心属性
        wfzGzftentry.setFvourtype(fpzz); //凭证字

        wfzGzftentry.setFcbzxffjg(fgzffjrjg); //金融机构
        wfzGzftentry.setFyhzh(fbanknumber); //银行账号
        wfzGzftentry.setFsscwzz(fcostcompany);
    }


    public WfzPerson getPerson(String personCode){
        WfzPerson wfzPerson = new WfzPerson();
        WfzPerson person = null;
        wfzPerson.setFnumber(personCode);
        List<WfzPerson> wfzPeople = wfzPersonService.selectWfzPersonList(wfzPerson);
        if (wfzPeople.size() > 0){
            person = wfzPeople.get(0);
        }

        return person;
    }

    /**
     * todo 通过盖雅编码还原EAS编码
     * @param unitCode 盖雅编码
     * @return
     *
     */
    public WfzBaseunit getUnitByGy(String unitCode){

        WfzBaseunit wfzBaseunit = new WfzBaseunit();
        wfzBaseunit.setFgynumber(unitCode);
        WfzBaseunit baseunit = null;
        List<WfzBaseunit> wfzBaseunits = wfzBaseunitService.selectWfzBaseunitList(wfzBaseunit);
        if (wfzBaseunits.size()>0){
            baseunit = wfzBaseunits.get(0);
        }
        return baseunit;
    }


    /**
     * @// TODO: 2023/3/4 根据金融机构和财务组织获取工资银行账号
     * @param fsscompany
     * @return
     */
    public String getBankNumBycomany(String fsscompany,String BillType,String fgzffjrjg){
        WfzBank wfzBank = new WfzBank();
        String fbanknumber = null;
        wfzBank.setFcompanynumber(fsscompany);
        wfzBank.setFtype(BillType);
        List<WfzBank> wfzBanks = wfzBankService.selectWfzBankList(wfzBank);
        if(wfzBanks.size()>0){
            WfzBank bank = wfzBanks.get(0);
            List<WfzBankentry> wfzBankentries = wfzBankMapper.selectBankEntry(wfzBanks.get(0).getFid(), fgzffjrjg);
            if(wfzBankentries.size()>=0){
                WfzBankentry wfzBankentry = wfzBankentries.get(0);
                fbanknumber = wfzBankentry.getFbanknumber();
            }
        }
        return fbanknumber;
    }
}
